#ifndef _KCP_AGENT_H_
#define _KCP_AGENT_H_

#include <arpa/inet.h>
#include <stdlib.h>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string.h>

#include "ikcp.h"

class PktData
{
public:
	PktData() 
	{
		memset(data_, 0, sizeof(data_));
		size_ = 0;
	}

	void operator=(const PktData &data)
	{
		memcpy(this->data_, data.data_, data.size_);
		this->size_ = data.size_;
	}
	
/*
	PktData operator=(const PktData &data)
	{
		memcpy(this->data_, data.data_, data.size_);
		this->size_ = data.size_;

		return *this;
	}
*/

	~PktData() {}

public:
	uint8_t data_[1500];
	int size_;
};

//using Fn_OutputProc = int (*)(const char *buf, int len, struct IKCPCB *kcp, void *user);

class KcpAgent
{
public:
	KcpAgent();
	~KcpAgent();

	void Handle();
	void Refresh();
	
	void SetClientAddr(struct sockaddr_in *addr);
	void AllocKcp(IUINT32 conv);
	void Feed(PktData data);
	void SetFd(int fd);

	void Send(std::string &buf);

	void Start();

	//Fn_OutputProc GetOutputProc()	{return OutputProc;}

private:
	void Update(IUINT32 current);
	static int OutputProc(const char *buf, int len, struct IKCPCB *kcp, void *user);

private:
	ikcpcb *kcp_;
	int sockfd_;
	char *id_;
	struct sockaddr_in client_addr_;
	char buf_[1500];
	bool processing_;

	std::mutex kcp_mtx_;

	std::mutex queue_mtx_;
	std::condition_variable queue_cv_;
	
	std::queue<PktData> buf_q_;

	uint32_t num_; //only for debug
};

#endif

